"""
Case Type   : cm_ctl
Case Name   : 集群故障测试-gaussdb主节点进程故障
Create At   : 2022-10-19
Owner       : opentestcase012
Description :
    1:查看集群状态
    2: kill掉 主节点gaussdb进程
    3: 查看后台进程，查看集群状态
Expect      :
    1:集群所有节点状态正常，显示Normal
    2:kill掉主节点gaussdb进程成功
    3:gaussdb主进程会立即被拉起，后台进程仍存在（pid发生变化），集群状态正常
History     :
"""

import os
import time
import unittest

from testcase.utils.Common import Common
from testcase.utils.CommonSH import CommonSH
from testcase.utils.Constant import Constant
from testcase.utils.Logger import Logger
from yat.test import Node
from yat.test import macro

Primary_SH = CommonSH('PrimaryDbUser')


@unittest.skipIf(3 != Primary_SH.get_node_num(), '需1主2备环境，否则不执行')
class DefinedResource(unittest.TestCase):
    def setUp(self):
        self.log = Logger()
        self.log.info(f'-----{os.path.basename(__file__)} start-----')
        self.pri_root = Node('PrimaryRoot')
        self.pri_user = Node('PrimaryDbUser')
        self.constant = Constant()
        self.common = Common()

    def test_cm(self):
        text = '----step1:查看集群状态; expect:集群状态正常,DN主在节点1----'
        self.log.info(text)
        show_status = f'source {macro.DB_ENV_PATH};' \
            f'cm_ctl query -Cv;'
        self.log.info(show_status)
        status_msg = self.common.get_sh_result(self.pri_user, show_status)
        self.assertIn(self.constant.CLUSTER_NORMAL_MSG, status_msg,
                      "执行失败:" + text)
        if '6001     P Primary Normal' not in status_msg:
            switch_cmd = f'source {macro.DB_ENV_PATH};' \
                f'cm_ctl switchover -a;' \
                f'sleep 5;' \
                f'cm_ctl query -Cv'
            self.log.info(switch_cmd)
            status_msg = self.common.get_sh_result(self.pri_user, switch_cmd)
            self.assertIn(self.constant.CLUSTER_NORMAL_MSG, status_msg,
                          "执行失败:" + text)
            self.assertIn('6001     P Primary Normal', status_msg,
                          "执行失败:" + text)

        text = '----查看gaussdb进程----'
        self.log.info(text)
        pro_cmd = '''ps ux|grep "gaussdb -D"|grep -v grep|\
        tr -s ' '|cut -d ' ' -f 2'''
        self.log.info(pro_cmd)
        process_old = self.common.get_sh_result(self.pri_user, pro_cmd)
        self.assertNotEqual('', process_old, "执行失败:" + text)

        text = '----step2:kill掉 主节点gaussdb进程; expect:成功----'
        self.log.info(text)
        kill_cmd = '''ps ux|grep "gaussdb -D"|grep -v grep|\
        tr -s ' '|cut -d ' ' -f 2|xargs kill -9;'''
        self.log.info(kill_cmd)
        kill_res = self.common.get_sh_result(self.pri_user, kill_cmd)
        self.assertEqual('', kill_res, "执行失败:" + text)

        text = '----step3:查看后台进程，查看集群状态; expect:gaussdb主进程会立即被拉起，' \
               '后台进程仍存在（pid发生变化），集群状态正常----'
        self.log.info(text)
        time.sleep(10)
        self.log.info(pro_cmd)
        process_new = self.common.get_sh_result(self.pri_user, pro_cmd)
        self.assertNotEqual('', process_new, "执行失败:" + text)
        self.assertNotEqual(process_new, process_old, "执行失败:" + text)
        time.sleep(10)
        self.log.info(show_status)
        status_msg = self.common.get_sh_result(self.pri_user, show_status)
        self.assertIn(self.constant.CLUSTER_NORMAL_MSG, status_msg,
                      "执行失败:" + text)
        self.assertIn('Primary Normal', status_msg, "执行失败:" + text)

    def tearDown(self):
        self.log.info('-----清理环境-----')
        text = '-----恢复集群状态; expect:成功-----'
        self.log.info(text)
        start_cmd = f'source {macro.DB_ENV_PATH};' \
            f'sleep 5;' \
            f'cm_ctl switchover -a;' \
            f'sleep 5;' \
            f'cm_ctl query -Civ;'
        self.log.info(start_cmd)
        start_msg = self.common.get_sh_result(self.pri_user, start_cmd)
        self.assertIn(self.constant.cm_switchover_success_msg, start_msg,
                      "执行失败:" + text)
        self.assertIn(self.constant.CLUSTER_NORMAL_MSG, start_msg,
                      "执行失败:" + text)
        self.log.info(f'-----{os.path.basename(__file__)} end-----')

